#include "php_dl.h"

zend_class_entry* php_class_library = NULL;

PHP_MINIT_FUNCTION(dl_library);
PHP_MSHUTDOWN_FUNCTION(dl_library);
PHP_RINIT_FUNCTION(dl_library);
PHP_RSHUTDOWN_FUNCTION(dl_library);
PHP_MINFO_FUNCTION(dl_library);

PHP_METHOD(Library, __construct);
PHP_METHOD(Library, __destructor);
PHP_METHOD(Library, call);

const zend_function_entry
		library_methods[] =
				{
								PHP_ME(Library, __construct, NULL, ZEND_ACC_PUBLIC| ZEND_ACC_CTOR) PHP_ME(Library, call, NULL, ZEND_ACC_PUBLIC)
				PHP_ME(Library, __destructor, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
				{	NULL, NULL, NULL}
			};

zend_module_entry dl_library_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
		STANDARD_MODULE_HEADER,
#endif
"dl_library"		,
		NULL,
		PHP_MINIT(dl_library),
		PHP_MSHUTDOWN(dl_library),
		PHP_RINIT(dl_library),
		PHP_RSHUTDOWN(dl_library),
		PHP_MINFO(dl_library),
#if ZEND_MODULE_API_NO >= 20010901
		"0.1",
#endif
		STANDARD_MODULE_PROPERTIES
	};

static HashTable libraries;

PHP_MINIT_FUNCTION(dl_library) {
	zend_class_entry dl;

	zend_hash_init(&libraries, 5, NULL, NULL, 0);

	INIT_CLASS_ENTRY(dl, "Library", library_methods);
	php_class_library = zend_register_internal_class(&dl TSRMLS_CC);
	php_class_library->ce_flags |= ZEND_ACC_FINAL_CLASS;

	return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(dl_library) {
	foreach(current, &libraries)

	endforeach();
	//unload_all_loaded_libraries();
	return SUCCESS;
}

PHP_RINIT_FUNCTION(dl_library) {
	return SUCCESS;
}

PHP_RSHUTDOWN_FUNCTION(dl_library) {
	return SUCCESS;
}

PHP_MINFO_FUNCTION(dl_library) {

}

DL_HANDLE handle = NULL;

PHP_METHOD(Library, __construct) {

	char* library_path;
	int library_path_length;
	zend_bool free = 0;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &library_path,
			&library_path_length, &free) == FAILURE) {
		zend_error(E_ERROR, "Missing the library path to load");
		return;
	}

	add_property_string(getThis(), "dlpath", library_path, 1);
	add_property_bool(getThis(), "free", free);

	handle = DL_LOAD(library_path);

	if (!handle) {
#ifdef DL_ERROR
		zend_error(E_ERROR, "An error occured during loading library: %s",
				DL_ERROR());
#else
		zend_error(E_ERROR, "An error occured during loading library");
#endif
		return;
	}
}

PHP_METHOD(Library, __destructor) {
	zend_bool free;

	zend_class_entry* clazz = zend_get_class_entry(getThis());

	free = Z_BVAL_P(zend_read_property(clazz, getThis(), "free", sizeof("free"), 1));
	char* dlname = Z_STRVAL_P(zend_read_property(clazz, getThis(), "dlpath", sizeof("dlpath"), 1));

	if(free) {
		zend_hash_del(&libraries, dlname, strlen(dlname));
	}

}

PHP_METHOD(Library, call) {

    zval*** args;
    char *fname;
    int fname_len, argc;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s+", &fname, &fname_len,&args, &argc) == FAILURE) {
		php_error(E_ERROR, "Missing the function name to call");
        return;
    }

	php_printf("Args pass: %d", argc);

}

ZEND_GET_MODULE(dl_library)
